﻿using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ShanghaiMetroAPP.Model
{
    public abstract class BaseListModel<T> : BaseModel, IEnumerable<T> where T : BaseModel,new()
    {
        /// <summary>
        /// 重写了中括号索引，当实例化基于BaseListModel的对象时，可通过对象名[0]的方式访问第1个元素。
        /// <para>Ex)</para>
        /// <para>var b = new ArrayListModel();</para>
        /// <para>var t = b[0] ---> 访问第1个元素</para>
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T this[int index] => data[index];

        protected List<T> data = new List<T>();
        public int Count => data.Count;
        public void Add(T t)
        {
            data.Add(t);
        }
        /// <summary>
        /// 在C#中，List和数组都实现了IEnumrable接口.
        /// 基于BaseListModel的所有类都实现了IEnumrable接口.
        /// </summary>
        /// <param name="enumerable"></param>
        public void Add(IEnumerable<T> enumerable)
        {
            data.AddRange(enumerable);
        }
        /// <summary>
        /// 会遍历所有组成员，传入一个函数用于处理成员。
        /// 当该函数返回false将会停止遍历。
        /// <para>Ex)</para>
        /// <para>var b = new ArrayListModel();</para>
        /// <para>b.ForEach((element)=> { return true;}); --->遍历所有b对象中的所有元素</para>
        /// </summary>
        /// <param name="func"></param>
        public void ForEach(Func<T,bool> func)
        {
            foreach(var element in data)
            {
                var result = func?.Invoke(element);
                if (result.HasValue && !result.Value)
                    //result非null，且result返回了false，则结束遍历
                    break;
            }
        }
        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return data.GetEnumerator();
        }

        public IEnumerator GetEnumerator()
        {
            return data.GetEnumerator();
        }
        public static W FromJson<W>(string json) where W: BaseListModel<T>,new()
        {
            var list = JsonConvert.DeserializeObject<List<T>>(json);
            return new W() { data = list };
        }
    }
}
